package com.alks.function.service.impl.finance.mtlcosts;

import com.alibaba.excel.util.StringUtils;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.common.utils.excelUtils.nestExcel.NestExcelUtil;
import com.alks.entity.data.entity.PcApAmt;
import com.alks.entity.data.entity.PcApAmtFk;
import com.alks.entity.data.enums.CompanyEnum;
import com.alks.entity.data.page.PageParam;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.InDataException;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.finance.ryfinance.ApAmtHeadDto;
import com.alks.function.data.request.finance.ryfinance.ApAmtHeadRequest;
import com.alks.function.data.vo.finance.mtlcosts.PcApAmtVo;
import com.alks.function.data.vo.finance.ryfinance.ApAmtHeadVO;
import com.alks.function.data.vo.finance.ryfinance.ApAmtDetailVO;
import com.alks.function.mapper.PcSlipDetailSoleMapper;
import com.alks.function.mapper.common.BackMapper;
import com.alks.function.mapper.finance.mtlcosts.*;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcMtlCheckMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcSlipDetailPartBfMapper;
import com.alks.function.service.finance.mtlcosts.IAllApAmtService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author MS
 * @since 2024/7/12下午6:32
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AllApAmtServiceImpl extends ServiceImpl<PcApAmtMapper, PcApAmt> implements IAllApAmtService {
    private final PcApAmtMapper amtMapper;
    private final PcApAmtFkMapper fkMapper;
    private final PcSlipDetailSoleMapper soleMapper;
    private final SD_SQ_PcSlipDetailPartBfMapper partBfMapper;
    private final PcSlipDetailPackBk0525Mapper bk0525Mapper;
    private final PcSlipDetailPackMapper detailPackMapper;
    private final PcOutListDetailBk0519Mapper bk0519Mapper;
    private final PcOutListDetail0922Mapper detail0922Mapper;
    private final PcOutListDetailMapper outDetailMapper;
    private final SD_SQ_PcMtlCheckMapper mtlCheckMapper;
    private final PcCostDetailMapper costDetailMapper;
    private final RedisService redisService;
    private final BackMapper backMapper;
    private final PcRecSlipReamrkMapper slipReamrkMapper;

    @Override
    @AutoPageAop
    public ResponseInfo tempQuery(ApAmtHeadRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        List<ApAmtHeadDto> dtos = amtMapper.amtTempQuery(request, companyId);
        BigDecimal amtSum = amtMapper.amtSumQuery(request, companyId);
        /*封装数据*/
        Map<String, Object> map = new HashMap<>(3);
        map.put("dtos", dtos);
        if (!request.getPageNum().equals(-1)&&!request.getPageSize().equals(-1)) {
            Page<ApAmtHeadDto> page = (Page<ApAmtHeadDto>) dtos;
            map.put("total", page.getTotal());
        }
        map.put("amtSum", amtSum);
        return ResponseInfo.ok(map);
    }

    @Override
    public void tempQueryExport(ApAmtHeadRequest request, HttpServletResponse response) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        List<ApAmtHeadDto> dtos = amtMapper.amtTempQuery(request, companyId);
        List<ApAmtHeadVO> vos = dtos.stream().map(e -> {
            ApAmtHeadVO vo = new ApAmtHeadVO();
            BeanUtil.copyProperties(e, vo);
            return vo;
        }).collect(Collectors.toList());
        ApAmtHeadVO totalVO = new ApAmtHeadVO();
        totalVO.setVendorName("合计");
        totalVO.setAmt(BigDecimal.valueOf(dtos.stream().mapToDouble(e->e.getAmt().doubleValue()).sum()));
        vos.add(totalVO);
        new NestExcelUtil<ApAmtHeadVO>().exportData(vos, null, "结算资料", response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInfo tempAdd(String financeYymm, String accountName, String vendorName) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String userName = tokenDTO.getUserName();
        String companyId = tokenDTO.getCompanyId();
        String balanceLeft = CompanyEnum.updateId(companyId)+"YF"+ LocalDate.now().format(DateTimeFormatter.ofPattern("yyMM"));
        /*获取数据*/
        /*收货对账作业-1数据*/
        List<PcApAmtVo> amtVoList = slipReamrkMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
//        List<PcApAmt> amt1 = soleMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
//        List<PcApAmt> amt2 = partBfMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
//        List<PcApAmt> amt3 = detailPackMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
//     0   List<PcApAmt> amt5 = mtlCheckMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
        /*费用结算-2/补单扣款-3 数据*/
        List<PcApAmt> amt6 = costDetailMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
        /*外发结算作业-4数据*/
        List<PcApAmt> amt4 = outDetailMapper.tempAddQuery(financeYymm, accountName, vendorName, companyId,userName);
        /*判断是否有数据*/
//        if (ArrayUtils.isEmpyt(amt1) && ArrayUtils.isEmpyt(amt2) && ArrayUtils.isEmpyt(amt3)
//                && ArrayUtils.isEmpyt(amt4) && ArrayUtils.isEmpyt(amt5) && ArrayUtils.isEmpyt(amt6)){
//            return ResponseInfo.error("没有可结算数据");
//        }
        if (ArrayUtils.isEmpyt(amtVoList) && ArrayUtils.isEmpyt(amt4) && ArrayUtils.isEmpyt(amt6)){
            return ResponseInfo.error("没有可结算数据");
        }
        /*生成结算单*/
        String balanceNoMax = amtMapper.balanceMaxQuery(balanceLeft);
        String newBalanceNo;
        if (StringUtils.isBlank(balanceNoMax)){
            newBalanceNo = balanceLeft + "00001";
        }else {
            String sequencePart = balanceNoMax.substring(8);
            int nextSequence = Integer.parseInt(sequencePart) + 1;
            newBalanceNo = balanceLeft + String.format("%05d", nextSequence);
            log.warn("{}",newBalanceNo);
        }
        String vendorNo = backMapper.getVendorNoByName(vendorName);
        /*更新原表单据号*/
        if (ArrayUtils.isNoEmpyt(amtVoList)){
            /*处理收货对账部分*/
            List<String> amt5 = amtVoList.stream()
                    .filter(a -> "面材".equals(a.getSeqName()))
                    .map(PcApAmtVo::getRecNo)
                    .collect(Collectors.toList());
            List<String> amt3 = amtVoList.stream()
                    .filter(a -> "包材".equals(a.getSeqName()))
                    .map(PcApAmtVo::getRecNo)
                    .collect(Collectors.toList());
            Set<String> seqNameSet = soleMapper.selectSeqName(financeYymm,companyId,accountName);
            List<String> amt1 = new ArrayList<>();
            if (ArrayUtils.isNoEmpyt(seqNameSet)){
            amt1 = amtVoList.stream()
                    .filter(a -> seqNameSet.contains(a.getSeqName()))
                    .map(PcApAmtVo::getRecNo)
                    .collect(Collectors.toList());
            }
            List<String> amt2 = amtVoList.stream()
                    .filter(a ->"易耗品".equals(a.getSeqName()))
                    .map(PcApAmtVo::getRecNo)
                    .collect(Collectors.toList());
            if (ArrayUtils.isNoEmpyt(amt1)){
                soleMapper.tempAddUp(financeYymm, accountName,vendorName,newBalanceNo,companyId);
            }if (ArrayUtils.isNoEmpyt(amt2)){
                partBfMapper.tempAddUp(financeYymm, accountName,amt2,newBalanceNo,companyId);
            }if (ArrayUtils.isNoEmpyt(amt3)){
                detailPackMapper.tempAddUp(financeYymm, accountName,amt3,newBalanceNo,companyId);
                bk0525Mapper.tempAddUp(financeYymm, accountName,amt3,newBalanceNo,companyId);
            }if (ArrayUtils.isNoEmpyt(amt5)){
                mtlCheckMapper.tempAddUp(financeYymm, accountName,amt5, newBalanceNo,companyId);
            }
        }
        if (ArrayUtils.isNoEmpyt(amt4)){
            outDetailMapper.tempAddUp(financeYymm, accountName, vendorName, newBalanceNo,companyId);
            bk0519Mapper.tempAddUp(financeYymm, accountName, vendorName, newBalanceNo,companyId);
            detail0922Mapper.tempAddUp(financeYymm, accountName, vendorName, newBalanceNo,companyId);
        }if (ArrayUtils.isNoEmpyt(amt6)){
            costDetailMapper.tempAddUp(financeYymm, accountName, vendorName, newBalanceNo,companyId);
        }
        /*新增结算数据*/
        BigDecimal item = BigDecimal.ZERO;
        List<PcApAmt> amtList = new ArrayList<>(amtVoList);
//        List<PcApAmt> amts = Stream.of(amt1, amt2, amt3, amt4, amt5, amt6)
//                .flatMap(List::stream).collect(Collectors.toList());
        List<PcApAmt> amts = Stream.of(amtList,amt4, amt6)
                .flatMap(List::stream).collect(Collectors.toList());
        for (PcApAmt amt : amts) {
            amt.setSysDate(LocalDateTime.now());
            amt.setSysUser(userName);
            amt.setSlipDate(LocalDate.now().atStartOfDay());
            amt.setSlipNo(newBalanceNo);
            amt.setVendorNo(vendorNo);
            amt.setItem(item);
            amt.setAccountName(accountName);
            BigDecimal a = amt.getAmt() == null ? BigDecimal.ZERO : amt.getAmt();
            amt.setAmt(a);
            item = item.add(BigDecimal.ONE);
            amtMapper.insert(amt);
        }
        /*写入明细数据*/
        return ResponseInfo.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInfo tempDel(String slipNo) {
        String companyId = UserIdThread.get().getCompanyId();
        String cfmFlag = "Y";
        /*获取数据*/
        LambdaQueryWrapper<PcApAmt> amtWrapper = new LambdaQueryWrapper<PcApAmt>()
                .eq(PcApAmt::getSlipNo, slipNo)
                .eq(PcApAmt::getCompanyId, companyId);
        List<PcApAmt> pcApAmts = amtMapper.selectList(amtWrapper);
        if (ArrayUtils.isEmpyt(pcApAmts)) {
            return ResponseInfo.error("单据不存在");
        }
        /*已检核不能删除*/
        Set<String> cfmSet = pcApAmts.stream().map(PcApAmt::getCfmFlag).collect(Collectors.toSet());
        if (ArrayUtils.isNoEmpyt(cfmSet) && cfmSet.contains(cfmFlag)) {
            return ResponseInfo.error("已检核，不能删除");
        }
        /*判断是否付款*/
        LambdaQueryWrapper<PcApAmtFk> fkWrapper = new LambdaQueryWrapper<PcApAmtFk>()
                .eq(PcApAmtFk::getSlipNo, slipNo)
                .eq(PcApAmtFk::getCompanyId, companyId);
        List<PcApAmtFk> fks = fkMapper.selectList(fkWrapper);
        if (ArrayUtils.isNoEmpyt(fks)) {
            return ResponseInfo.error("已付款，不能删除");
        }
        /*删除数据*/
        amtMapper.delete(amtWrapper);
        soleMapper.tempDel(slipNo,companyId);
        partBfMapper.tempDel(slipNo,companyId);
        detailPackMapper.tempDel(slipNo,companyId);
        bk0525Mapper.tempDel(slipNo,companyId);
        outDetailMapper.tempDel(slipNo,companyId);
        mtlCheckMapper.tempDel(slipNo,companyId);
        costDetailMapper.tempDel(slipNo,companyId);
        bk0519Mapper.tempDel(slipNo,companyId);
        detail0922Mapper.tempDel(slipNo,companyId);
        return ResponseInfo.ok();
    }

    @AutoPageAop
    @Override
    public ResponseInfo detailQuery(PageParam request, String slipNo, Integer flag) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取明细数据*/
        List<PcApAmt> apAmts = amtMapper.getBySlipNo(slipNo,flag,companyId);
        Page<PcApAmt> page = (Page<PcApAmt>) apAmts;
        /*获取求和*/
        List<PcApAmt> apAmtSums = lambdaQuery()
                .select(PcApAmt::getQty, PcApAmt::getAmt)
                .eq(PcApAmt::getSlipNo, slipNo)
                .eq(PcApAmt::getCompanyId, companyId).list();
        BigDecimal amtSum = apAmtSums.stream()
                .map(PcApAmt::getAmt)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(2, RoundingMode.HALF_UP);
        BigDecimal qtySum = apAmtSums.stream()
                .map(PcApAmt::getQty)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(2, RoundingMode.HALF_UP);
        /*数字截取*/
        for (PcApAmt apAmt : apAmts) {
            apAmt.setPrice(scale(apAmt.getPrice()));
            apAmt.setAmt(scale(apAmt.getAmt()));
            apAmt.setQty(scale(apAmt.getQty()));
        }
        /*封装返回*/
        Map<String, Object> map = new HashMap<>(4);
        map.put("dtos", apAmts);
        map.put("total", page.getTotal());
        map.put("amtSum", amtSum);
        map.put("qtySum", qtySum);
        return ResponseInfo.ok(map);
    }

    @Override
    public List<ApAmtDetailVO> detailQueryExport(String slipNo, boolean aggr) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取明细数据*/
        List<PcApAmt> apAmts = lambdaQuery()
                .eq(PcApAmt::getSlipNo, slipNo)
                .eq(PcApAmt::getCompanyId, companyId)
                .list();
        if (aggr) {
            Function<PcApAmt, List<Object>> keyExtractor = e ->
                    Arrays.asList(e.getMtlName(), e.getMtlUnit(), e.getMtlColor(), e.getMtlSpec());
            Map<List<Object>, List<PcApAmt>> aggregatedData = apAmts.stream().collect(
                    Collectors.groupingBy(keyExtractor));
            apAmts = new ArrayList<>();
            for (Map.Entry<List<Object>, List<PcApAmt>> entry : aggregatedData.entrySet()) {
                PcApAmt apAmt = entry.getValue().get(0);
                apAmt.setQty(BigDecimal.valueOf(entry.getValue().stream().filter(Objects::nonNull).filter(e->e.getQty()!=null).mapToLong(e->e.getQty().longValue()).sum()));
                apAmt.setAmt(BigDecimal.valueOf(entry.getValue().stream().filter(Objects::nonNull).filter(e->e.getAmt()!=null).mapToDouble(e->e.getAmt().doubleValue()).sum()));
                apAmts.add(apAmt);
            }
        }
        List<ApAmtDetailVO> vos = apAmts.stream().map(e -> {
            ApAmtDetailVO vo = new ApAmtDetailVO();
            BeanUtil.copyProperties(e, vo);
            return vo;
        }).collect(Collectors.toList());
        ApAmtDetailVO totalVO = new ApAmtDetailVO();
        totalVO.setMtlUnit("合计");
        totalVO.setQty(BigDecimal.valueOf(apAmts.stream().filter(Objects::nonNull).filter(e->e.getQty()!=null).mapToLong(e->e.getQty().longValue()).sum()));
        totalVO.setAmt(BigDecimal.valueOf(apAmts.stream().filter(Objects::nonNull).filter(e->e.getAmt()!=null).mapToDouble(e->e.getAmt().doubleValue()).sum()));
        vos.add(totalVO);
        return vos;
    }

    private static BigDecimal scale(BigDecimal num){
        num = num==null?BigDecimal.ZERO:num.setScale(2, RoundingMode.HALF_UP);
        return num;
    }

    @Override
    public ResponseInfo cfm(List<String> slipNos, String cfmFlag) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        String cfm = "Y";
        /*判断是否存在付款*/
        LambdaQueryWrapper<PcApAmtFk> fkWrapper = new LambdaQueryWrapper<PcApAmtFk>()
                .in(PcApAmtFk::getSlipNo, slipNos)
                .eq(PcApAmtFk::getCompanyId, companyId)
                .last("LIMIT 1");
        PcApAmtFk fk = fkMapper.selectOne(fkWrapper);
        if (!BeanUtil.isEmpty(fk)) {
            return ResponseInfo.error("存在包含" + fk.getSlipNo() + "在内单据已付款，不能检核");
        }
        /*更新数据*/
        LambdaUpdateWrapper<PcApAmt> wrapper = new LambdaUpdateWrapper<PcApAmt>()
                .in(PcApAmt::getSlipNo, slipNos)
                .eq(PcApAmt::getCompanyId, companyId)
                .isNull(cfm.equals(cfmFlag), PcApAmt::getCfmFlag)
                .eq(!cfm.equals(cfmFlag), PcApAmt::getCfmFlag, "Y");
        /*如果前端没拦截或直接访问接口输入参数，重复检核或者取消检核则报错可能会具有迷惑性*/
        List<PcApAmt> pcApAmts = amtMapper.selectList(wrapper);
        if (ArrayUtils.isEmpyt(pcApAmts)) {
            return ResponseInfo.error("请勿重复检核或取消检核");
        }
        if (cfm.equals(cfmFlag)) {
            wrapper.set(PcApAmt::getCfmFlag, cfm)
                    .set(PcApAmt::getCfmDate, LocalDateTime.now())
                    .set(PcApAmt::getCfmUser, userName);
        } else {
            /*判断是否是本人数据*/
            if (!pcApAmts.stream().allMatch(e -> e.getCfmUser().equals(userName))) {
                return ResponseInfo.error("非本人数据无法取消");
            }
            wrapper.set(PcApAmt::getCfmFlag, null)
                    .set(PcApAmt::getCfmDate, null)
                    .set(PcApAmt::getCfmUser, null);
        }
        amtMapper.update(null, wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo fkQuery(String slipNo) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        LambdaQueryWrapper<PcApAmtFk> wrapper = new LambdaQueryWrapper<PcApAmtFk>()
                .eq(PcApAmtFk::getSlipNo, slipNo)
                .eq(PcApAmtFk::getCompanyId, companyId);
        List<PcApAmtFk> dtos = fkMapper.selectList(wrapper);
        BigDecimal amtSum = dtos.stream().map(PcApAmtFk::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
        Map<String, Object> map = new HashMap<>(2);
        map.put("dtos", dtos);
        map.put("amtSum", amtSum);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo fkUp(PcApAmtFk request, BigDecimal amtOld, String vendorNameOld) {
        String companyId = UserIdThread.get().getCompanyId();
        /*判断订单号是否为空*/
        String slipNo = request.getSlipNo();
        if (StringUtil.isBlank(slipNo)) {
            return ResponseInfo.error("订单号不能为空");
        }
        /*判断数据是否存在*/
        LambdaUpdateWrapper<PcApAmtFk> wrapper = new LambdaUpdateWrapper<PcApAmtFk>()
                .eq(PcApAmtFk::getSlipNo, slipNo)
                .eq(PcApAmtFk::getSlipDate, request.getSlipDate());
        BigDecimal sendSum = fkMapper.selectList(wrapper).stream()
                .filter(Objects::nonNull)
                .map(PcApAmtFk::getAmt)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (request.getItem() != null) {
            wrapper.eq(PcApAmtFk::getItem, request.getItem())
                    .last("LIMIT 1");
        } else {
            wrapper.eq(PcApAmtFk::getAmt, amtOld)
                    .eq(PcApAmtFk::getVendorName, vendorNameOld)
                    .last("LIMIT 1");
        }
        /*付款检核*/
        PcApAmtFk fk = fkMapper.selectOne(wrapper);
        if (BeanUtil.isEmpty(fk)) {
            return ResponseInfo.error("单据号不存在");
        }
        fkCheck(request.getAmt(), slipNo, companyId, sendSum, fk.getAmt());
        wrapper.set(PcApAmtFk::getAmt, request.getAmt())
                .set(PcApAmtFk::getVendorName, request.getVendorName())
                .set(PcApAmtFk::getRemark, request.getRemark())
                .set(PcApAmtFk::getApCheckDate, request.getApCheckDate());
        fkMapper.update(null, wrapper);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo fkAdd(PcApAmtFk request) {
        request.setId(null);
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        lambdaQuery()
                .eq(PcApAmt::getSlipNo, request.getSlipNo())
                .eq(PcApAmt::getCompanyId, companyId);
        /*获取序号*/
        LambdaQueryWrapper<PcApAmtFk> wrapper = new LambdaQueryWrapper<PcApAmtFk>()
                .eq(PcApAmtFk::getSlipNo, request.getSlipNo())
                .eq(PcApAmtFk::getCompanyId, companyId);
        List<PcApAmtFk> fks = fkMapper.selectList(wrapper);
        BigDecimal sendQty = BigDecimal.ZERO;
        long item = 0L;
        if (ArrayUtils.isNoEmpyt(fks)) {
            item = fks.stream().filter(Objects::nonNull).mapToLong(PcApAmtFk::getItem).max().orElse(0L) + 1L;
            sendQty = fks.stream().map(PcApAmtFk::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        /*付款检核*/
        fkCheck(request.getAmt(), request.getSlipNo(), companyId, sendQty, BigDecimal.ZERO);
        /*补充数据*/
        request.setCompanyId(companyId);
        request.setItem(item);
        request.setSysDate(LocalDateTime.now());
        request.setSysUser(userName);
        fkMapper.insert(request);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo fkDel(String id) {
        String companyId = UserIdThread.get().getCompanyId();
        /*判断数据合法性*/
        PcApAmtFk fk = fkMapper.selectById(id);
        if (fk==null||!companyId.equals(fk.getCompanyId())){
            throw new ServiceErrorException("数据失效");
        }
        /*未检核不能删除*/
        Integer count = lambdaQuery()
                .eq(PcApAmt::getSlipNo, fk.getSlipNo())
                .eq(PcApAmt::getCompanyId, companyId)
                .isNull(PcApAmt::getCfmFlag).count();
        if (count > 0) {
            return ResponseInfo.error("数据未检核");
        }
        /*删除数据*/
        fkMapper.deleteById(id);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo aftPayProcess(List<String> slipNos) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        /*去重*/
        slipNos = slipNos.stream().distinct().collect(Collectors.toList());
        /*获取应发数量*/
        List<PcApAmt> apAmts = lambdaQuery()
                .in(PcApAmt::getSlipNo, slipNos)
                .eq(PcApAmt::getCompanyId, companyId).list();
        if (ArrayUtils.isEmpyt(apAmts)) {
            return ResponseInfo.error("数据不存在");
        }
        Map<String, BigDecimal> amtMap = apAmts.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.toMap(PcApAmt::getSlipNo, PcApAmt::getAmt, BigDecimal::add));
        if (amtMap.size() != slipNos.size()) {
            return ResponseInfo.error("数据不存在");
        }
        LambdaQueryWrapper<PcApAmtFk> queryWrapper = new LambdaQueryWrapper<PcApAmtFk>()
                .in(PcApAmtFk::getSlipNo, slipNos)
                .eq(PcApAmtFk::getCompanyId, companyId);
        List<PcApAmtFk> fks = fkMapper.selectList(queryWrapper);
        Map<String, Long> itemMap = new HashMap<>(slipNos.size());
        /*处理存在发货数量的数据*/
        if (ArrayUtils.isNoEmpyt(fks)) {
            Map<String, BigDecimal> sendMap = fks.stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toMap(PcApAmtFk::getSlipNo, PcApAmtFk::getAmt, BigDecimal::add));
            for (String slipNo : slipNos) {
                BigDecimal sendAmt = sendMap.get(slipNo) == null ? BigDecimal.ZERO : sendMap.get(slipNo);
                BigDecimal amt = amtMap.get(slipNo).subtract(sendAmt);
                amtMap.put(slipNo, amt);
            }
            /*获取序号数据*/
            itemMap = fks.stream()
                    .collect(Collectors.groupingBy(PcApAmtFk::getSlipNo,
                            Collectors.collectingAndThen(
                                    Collectors.maxBy(Comparator.comparing(PcApAmtFk::getItem)),
                                    maxItem -> maxItem.map(fk -> fk.getItem() + 1).orElse(1L)
                            )
                    ));
        }
        /*更新数据*/
        for (String slipNo : slipNos) {
            Long item = itemMap.get(slipNo)==null?0L:itemMap.get(slipNo);
            PcApAmtFk fk = new PcApAmtFk();
            fk.setCompanyId(companyId);
            fk.setSlipNo(slipNo);
            fk.setVendorName("尾款处理");
            fk.setVendorNo("WKCL");
            fk.setAmt(amtMap.get(slipNo));
            fk.setSysDate(LocalDateTime.now());
            fk.setSysUser(userName);
            fk.setItem(item);
            fkMapper.insert(fk);
        }
        return ResponseInfo.ok();
    }

    @Override
    public List<Map<String, String>> vendor(String financeYymm, String accountName) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        List<Map<String,String>> vendorList1 = slipReamrkMapper.vendorBack(financeYymm,accountName,companyId);
        List<Map<String,String>> vendorList2 = costDetailMapper.vendorBack(financeYymm,accountName,companyId);
        List<Map<String,String>> vendorList3 = outDetailMapper.vendorBack(financeYymm,accountName,companyId);
        /*组装数据*/
        List<Map<String,String>> vendorList = Stream.of(vendorList1,vendorList2,vendorList3)
                .flatMap(List::stream).collect(Collectors.toList());
        return vendorList;
    }

    @Override
    public Map<String, Integer> detailPrint(String slipNo) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取单据笔数*/
        Map<String,Integer> map = new HashMap<>(2);
        Integer slipCount = amtMapper.selectSlipCount(slipNo, companyId);
        /*获取打印次数*/
        LambdaUpdateWrapper<PcApAmt> wrapper = new LambdaUpdateWrapper<PcApAmt>()
                .eq(PcApAmt::getSlipNo,slipNo)
                .eq(PcApAmt::getCompanyId,companyId);
        List<PcApAmt> amtList = amtMapper.selectList(wrapper);
        int printCount = amtList == null ? 1 :
                amtList.stream()
                        .filter(Objects::nonNull)
                        .map(PcApAmt::getPrintCount)
                        .filter(Objects::nonNull)
                        .min(Integer::compareTo)
                        .orElse(0)+1;
        /*打印次数+1*/
        wrapper.set(PcApAmt::getPrintCount,printCount);
        amtMapper.update(null,wrapper);
        map.put("slipCount",slipCount);
        map.put("printCount",printCount);
        return map;
    }

    /**
     * 付款前检核
     *
     * @param newAmt    新金额
     * @param slipNo    单据号
     * @param companyId 公司id
     * @param sendSum   已付款金额
     * @param oldAmt    旧金额
     */
    private void fkCheck(BigDecimal newAmt, String slipNo, String companyId, BigDecimal sendSum, BigDecimal oldAmt) {
        /*存在未检核则不能修改*/
        List<PcApAmt> apAmts = lambdaQuery()
                .eq(PcApAmt::getSlipNo, slipNo)
                .eq(PcApAmt::getCompanyId, companyId).list();
        List<PcApAmt> noCfmList = apAmts.stream()
                .filter(a -> StringUtil.isBlank(a.getCfmFlag()))
                .collect(Collectors.toList());
        if (ArrayUtils.isNoEmpyt(noCfmList)) {
            throw new ServiceErrorException("记录未检核");
        }
        /*金额检核*/
        BigDecimal amtSum = apAmts.stream().map(PcApAmt::getAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal unSendAmt = amtSum.setScale(2, RoundingMode.HALF_UP)
                .subtract(sendSum)
                .add(oldAmt)
                .subtract(newAmt);        if (unSendAmt.compareTo(BigDecimal.ZERO) < 0) {
            throw new InDataException("付款金额不能大于未付款金额");
        }
    }
}
